# coding=utf-8
import errno
import os
from zfec import filefec
from multiprocessing import Pool

from utility import make_sure_directory_exists


def unwrap_self_f(arg, **kwargs):
    return Encoder.encode_file(*arg, **kwargs)


class Encoder:

    def __init__(self, k, n, root_source_path, target_root_path, suffix):
        self.k = k
        self.n = n
        self.root_source_path = root_source_path
        self.target_root_path = target_root_path
        self.suffix = suffix

    def encode_file(self, file_path):
        prefix = os.path.basename(file_path)
        print("prefix: " + prefix)
        relative_path = os.path.join(os.path.dirname(os.path.relpath(file_path, self.root_source_path)), prefix)
        # print("relative path = " + relative_path)
        output_path = os.path.join(self.target_root_path, relative_path)
        make_sure_directory_exists(output_path)
        filesize = os.stat(file_path).st_size
        # TODO: 这里不用打开 file_path ， 只需要传过来一个加密好的小文件的对象作为 f 传进 "filefec.encode_to_files()" 函数中就行
        with open(file_path, 'rb') as f:
            filefec.encode_to_files(f, filesize, output_path, prefix, self.k, self.n, self.suffix, False, False)

    def traverse_and_identify_files(self):
        file_paths = []
        for root, dirs, files in os.walk(self.root_source_path):
            for file_name in files:
                file_paths.append(os.path.join(root, file_name))
        return file_paths

    def encode_directory(self):
        make_sure_directory_exists(self.target_root_path)
        files = self.traverse_and_identify_files()
        p = Pool(4)
        p.map(unwrap_self_f, zip([self] * len(files), files))
